import argparse
import ctypes
import os
import stat
import sys
import time


def is_admin():
    """检查是否以管理员权限运行"""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def safe_listdir(path):
    """安全地列出目录内容，处理权限问题"""
    try:
        return os.listdir(path)
    except PermissionError:
        return []
    except FileNotFoundError:
        return []
    except Exception as e:
        print(f"警告: 无法访问 {path} - {str(e)}")
        return []

def safe_remove(path, is_file=False):
    """安全地删除文件或目录"""
    try:
        # 尝试更改权限
        try:
            os.chmod(path, stat.S_IWRITE)
        except:
            pass

        if is_file:
            os.remove(path)
        else:
            os.rmdir(path)
        return True
    except PermissionError:
        return False
    except FileNotFoundError:
        return False
    except Exception as e:
        print(f"删除失败: {path} - {str(e)}")
        return False

def remove_empty_items(path, verbose=False, skip_protected=True, remove_zero_byte_files=False):
    """递归删除空文件夹和零字节文件"""
    if not os.path.exists(path):
        return 0

    deleted_count = 0

    # 如果是文件
    if os.path.isfile(path):
        if remove_zero_byte_files and os.path.getsize(path) == 0:
            if safe_remove(path, is_file=True):
                if verbose:
                    print(f"删除零字节文件: {path}")
                return 1
            elif verbose:
                print(f"无法删除文件: {path} (权限不足)")
        return 0

    # 检查是否是受保护的系统文件夹
    if skip_protected:
        protected_keywords = ["Program Files", "Windows", "AppData", "Application Data", "ProgramData"]
        if any(keyword in path for keyword in protected_keywords):
            if verbose:
                print(f"跳过系统文件夹: {path}")
            return 0

    # 获取目录内容（安全方式）
    items = safe_listdir(path)
    if items is None:  # 表示访问失败
        return 0

    # 先处理子目录和文件
    for item in items:
        item_path = os.path.join(path, item)
        deleted_count += remove_empty_items(item_path, verbose, skip_protected, remove_zero_byte_files)

    # 再次检查目录是否存在（可能在递归中被删除）
    if not os.path.exists(path):
        return deleted_count

    # 重新获取目录内容（因为可能已经删除了部分内容）
    items = safe_listdir(path)

    # 检查当前文件夹是否为空
    if len(items) == 0:
        if safe_remove(path):
            if verbose:
                print(f"删除空文件夹: {path}")
            return deleted_count + 1
        elif verbose:
            print(f"无法删除文件夹: {path} (权限不足)")

    return deleted_count

def main():
    parser = argparse.ArgumentParser(description='清理指定目录中的空文件夹和零字节文件')
    parser.add_argument('path', nargs='?', default=os.getcwd(),
                        help='目标目录路径 (默认为当前目录)')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='显示详细操作信息')
    parser.add_argument('-c', '--confirm', action='store_true',
                        help='执行前需要确认')
    parser.add_argument('-f', '--force', action='store_true',
                        help='尝试删除系统文件夹 (需要管理员权限)')
    parser.add_argument('-z', '--zero-byte', action='store_true',
                        help='同时删除零字节文件')

    args = parser.parse_args()
    target_dir = os.path.abspath(args.path)

    if not os.path.exists(target_dir):
        print(f"错误: 目录不存在 - {target_dir}")
        sys.exit(1)

    print(f"开始扫描: {target_dir}")

    if args.confirm:
        action = "清理空文件夹"
        if args.zero_byte:
            action += "和零字节文件"
        response = input(f"确定要{action}吗? (y/n): ")
        if response.lower() != 'y':
            print("操作已取消")
            sys.exit(0)

    # 检查是否需要管理员权限
    if args.force and not is_admin():
        print("警告: 需要管理员权限来删除系统文件夹")
        # 尝试以管理员身份重新启动
        ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
        sys.exit(0)

    print("正在扫描并删除...")
    start_time = time.time()
    deleted_count = remove_empty_items(target_dir, args.verbose, not args.force, args.zero_byte)
    elapsed_time = time.time() - start_time

    if deleted_count > 0:
        print(f"清理完成! 共删除 {deleted_count} 个空项目 (耗时: {elapsed_time:.2f}秒)")
    else:
        print("未找到可删除的空文件夹或零字节文件")

if __name__ == "__main__":
    main()